import { Mesh, MeshBasicMaterial, OrthographicCamera, PlaneBufferGeometry, Scene, ShaderMaterial, Vector3, WebGLRenderer } from "three"

const canvas = document.createElement('canvas')
document.body.appendChild(canvas)
canvas.style.width = '100vw'
canvas.style.height = '100vh'

const scene = new Scene()
const renderer = new WebGLRenderer({
  antialias: true,
  canvas
})
renderer.autoClearColor = false

const camera = new OrthographicCamera(
  -1, // left
  1, // right
  1, // top
  -1, // bottom
  -1, // near
  1,  // far
)
const plane = new PlaneBufferGeometry(2, 3)

const fragmentShader = `
#include <common>

uniform float iTime;
uniform vec3 iResolution;
// 定义一个速度对象
uniform float SPEED;

const float ARC_RADIUS = 0.7;
const float ARC_WIDTH = 0.02;
const float ARC_LENGTH = 1.5;
const float SMOOTHNESS = 1.5;

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    //vec2 uv = fragCoord.xy/iResolution.xy;
    //uv.x *= iResolution.x/iResolution.y;
    //uv = uv*2.0-vec2(1.0);
    vec2 uv = ( 2.0*fragCoord -iResolution.xy ) / iResolution.y;
    
    float angle_offset = mod(iTime*SPEED,PI2)-PI;
    float r = uv.x*uv.x +uv.y*uv.y;
    float angle = uv.x==0.0?0.0:atan(uv.y,uv.x);
    float delta_angle = angle_offset - angle;
    delta_angle = mod(delta_angle+PI2,PI2);
    
    float circle = 1.0-smoothstep(0.0,ARC_WIDTH,abs(r-ARC_RADIUS));
    float fan = 1.0-smoothstep(ARC_LENGTH-SMOOTHNESS,ARC_LENGTH, abs(delta_angle-ARC_LENGTH));
    float value = circle*fan;
    
    vec3 color = vec3(value);
    fragColor = vec4(color,1.0);
}

void main() {
  mainImage(gl_FragColor, gl_FragCoord.xy);
}
`

// const material = new MeshBasicMaterial({ color: 'red' })
const uniforms = {
  iTime: { value: 0},
  iResolution: { value: new Vector3() },
  SPEED: { value: 2.5 }
}
const material = new ShaderMaterial({
  // 片元着色器
  fragmentShader,
  // uniforms 与片元着色器中的变量名对应
  uniforms
})
scene.add(new Mesh(plane, material))


function resizeRendererToDisplaySize(renderer: WebGLRenderer) {
  const canvas = renderer.domElement
  const width = canvas.clientWidth
  const height = canvas.clientHeight
  const needResize = canvas.width !== width || canvas.height !== height

  if (needResize) {
    renderer.setSize(width, height, false)
  }

  return needResize
}

function render(time) {
  time *= 0.001

  resizeRendererToDisplaySize(renderer)

  const canvas = renderer.domElement
  uniforms.iResolution.value.set(canvas.width, canvas.height, 1)
  uniforms.iTime.value = time

  renderer.render(scene, camera)

  requestAnimationFrame(render)
}

requestAnimationFrame(render)